package com.ruoyi.life.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.life.domain.vo.CreateBillVo;
import com.ruoyi.life.domain.vo.QyEnterpriseOtherFeeVO;
import com.ruoyi.life.mapper.*;
import com.ruoyi.life.service.IFeBillService;
import com.ruoyi.life.service.IFeLeaseRecordService;
import com.ruoyi.life.service.manager.BuiRoomManager;
import com.ruoyi.omp.api.domain.*;
import com.ruoyi.omp.api.domain.vo.RoomVO;
import com.ruoyi.omp.api.enums.FeeTypeEnum;
import com.ruoyi.omp.api.enums.LeaseStateEnum;
import com.ruoyi.system.api.LinkFileServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

//import com.sun.javaws.exceptions.OfflineLaunchException;

/**
 * 租赁记录Service业务层处理
 *
 * @author cjie
 * @date 2021-09-17
 */
@Service
@Slf4j
public class FeLeaseRecordServiceImpl extends LinkFileServiceImpl implements IFeLeaseRecordService {
    @Autowired
    private FeLeaseRecordMapper feLeaseRecordMapper;
//    @Autowired
//    private RemoteRoomService roomService;

    @Autowired
    private BuiRoomManager roomManager;

    @Autowired
    private FeOfficeMapper feOfficeMapper;
    @Autowired
    private FeApartmentMapper feApartmentMapper;
    @Autowired
    private FePropertyMapper fePropertyMapper;
    @Autowired
    private FeFacilityMapper feFacilityMapper;

    @Autowired
    private FeSuretyMapper suretyMapper;

    @Autowired
    private IFeBillService billService;

    /**
     * 查询租赁记录
     *
     * @param id 租赁记录ID
     * @return 租赁记录
     */
    @Override
    public FeLeaseRecord selectFeLeaseRecordById(String id) {
        FeLeaseRecord feLeaseRecord = feLeaseRecordMapper.selectFeLeaseRecordById(id);
        List<RoomVO> roomVOList = feLeaseRecordMapper.selectRoomByRecordId(id);
        feLeaseRecord.setRoomVOList(roomVOList);
        feLeaseRecord.setFileList(getFileList(id));

        if (StringUtils.isNotEmpty(feLeaseRecord.getOfficeFeeId())) {
            feLeaseRecord.setFeOffice(feOfficeMapper.selectFeOfficeById(feLeaseRecord.getOfficeFeeId()));
        }

        if (StringUtils.isNotEmpty(feLeaseRecord.getApartmentFeeId())) {
            feLeaseRecord.setFeApartment(feApartmentMapper.selectFeApartmentById(feLeaseRecord.getApartmentFeeId()));
        }
        if (StringUtils.isNotEmpty(feLeaseRecord.getPropertyFeeId())) {
            feLeaseRecord.setFeProperty(fePropertyMapper.selectFePropertyById(feLeaseRecord.getPropertyFeeId()));
        }
        if (StringUtils.isNotEmpty(feLeaseRecord.getFacilityFeeId())) {
            feLeaseRecord.setFeFacility(feFacilityMapper.selectFeFacilityById(feLeaseRecord.getFacilityFeeId()));
            FeFacility feFacility = feLeaseRecord.getFeFacility();
            if (feFacility != null) {
                feFacility.setFirstFacilityFee(feFacility.getFirstYearFacilityFee() + "/" + feFacility.getFirstYearTotal());
                feFacility.setSecondFacilityFee(feFacility.getSecondYearFacilityFee() + "/" + feFacility.getSecondYearTotal());
                feFacility.setThirdFacilityFee(feFacility.getThirdYearFacilityFee() + "/" + feFacility.getThirdYearTotal());
                feFacility.setFourthFacilityFee(feFacility.getFourthYearFacilityFee() + "/" + feFacility.getFourthYearTotal());
                feFacility.setFifthFacilityFee(feFacility.getFifthYearFacilityFee() + "/" + feFacility.getFifthYearTotal());
            }
        }

        FeSurety query = new FeSurety();
        query.setLeaseId(id);
        List<FeSurety> list = suretyMapper.selectFeSuretyList(query);
        if (list.size() > 0) {
            feLeaseRecord.setFeSurety(list.get(0));
        }
        return feLeaseRecord;
    }

    /**
     * 查询租赁记录列表
     *
     * @param feLeaseRecord 租赁记录
     * @return 租赁记录
     */
    @Override
    public List<FeLeaseRecord> selectFeLeaseRecordList(FeLeaseRecord feLeaseRecord) {
        List<FeLeaseRecord> list = feLeaseRecordMapper.selectFeLeaseRecordList(feLeaseRecord);
        list.stream().forEach(o -> {
            FeSurety query = new FeSurety();
            query.setLeaseId(o.getId());
            List<FeSurety> feSureties = suretyMapper.selectFeSuretyList(query);
            if (feSureties.size() > 0) {
                o.setFeSurety(feSureties.get(0));
            }
        });
        return list;
    }

    /**
     * 通过企业id查询租赁记录
     *
     * @param enterpriseId 租赁记录
     * @return 租赁记录
     */
    @Override
    public FeLeaseRecord selectFeLeaseRecordByEnterpriseId(String enterpriseId) {
        return feLeaseRecordMapper.selectFeLeaseRecordByEnterpriseId(enterpriseId);
    }

    @Override
    public List<FeLeaseRecord> getRecordListByEnterpriseId(String enterpriseId) {
        FeLeaseRecord query = new FeLeaseRecord();
        query.setEnterpriseId(enterpriseId);
        List<FeLeaseRecord> list = feLeaseRecordMapper.selectFeLeaseRecordList(query);
        list.forEach(o ->{
            List<RoomVO> roomVOList = feLeaseRecordMapper.selectRoomByRecordId(o.getId());
            o.setRoomVOList(roomVOList);
            if (StringUtils.isNotEmpty(o.getOfficeFeeId())) {
                o.setFeOffice(feOfficeMapper.selectFeOfficeById(o.getOfficeFeeId()));
            }

            if (StringUtils.isNotEmpty(o.getApartmentFeeId())) {
                o.setFeApartment(feApartmentMapper.selectFeApartmentById(o.getApartmentFeeId()));
            }
            if (StringUtils.isNotEmpty(o.getPropertyFeeId())) {
                o.setFeProperty(fePropertyMapper.selectFePropertyById(o.getPropertyFeeId()));
            }
            if (StringUtils.isNotEmpty(o.getFacilityFeeId())) {
                o.setFeFacility(feFacilityMapper.selectFeFacilityById(o.getFacilityFeeId()));
                FeFacility feFacility = o.getFeFacility();
                if (feFacility != null) {
                    feFacility.setFirstFacilityFee(feFacility.getFirstYearFacilityFee() + "/" + feFacility.getFirstYearTotal());
                    feFacility.setSecondFacilityFee(feFacility.getSecondYearFacilityFee() + "/" + feFacility.getSecondYearTotal());
                    feFacility.setThirdFacilityFee(feFacility.getThirdYearFacilityFee() + "/" + feFacility.getThirdYearTotal());
                    feFacility.setFourthFacilityFee(feFacility.getFourthYearFacilityFee() + "/" + feFacility.getFourthYearTotal());
                    feFacility.setFifthFacilityFee(feFacility.getFifthYearFacilityFee() + "/" + feFacility.getFifthYearTotal());
                }
            }

            FeSurety feSurety = new FeSurety();
            feSurety.setLeaseId(o.getId());
            List<FeSurety> feSureties = suretyMapper.selectFeSuretyList(feSurety);
            if (feSureties.size() > 0) {
                o.setFeSurety(feSureties.get(0));
            }

        });
        return list;
    }

    /**
     * 新增租赁记录
     *
     * @param feLeaseRecord 租赁记录
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized int insertFeLeaseRecord(FeLeaseRecord feLeaseRecord) {
        if (StringUtils.isBlank(feLeaseRecord.getId())) {
            feLeaseRecord.setId(IdUtil.getSnowflake(0, 0).nextIdStr());
        }
        feLeaseRecord.setCreateTime(DateUtils.getNowDate());
        feLeaseRecord.setCreateBy(SecurityUtils.getUsername());

        linkFile(feLeaseRecord.getFileIdList(), feLeaseRecord.getId());

        //修改房屋状态为已租赁，并设置租赁记录id
        if (feLeaseRecord.getRoomIdList() != null && feLeaseRecord.getRoomIdList().size() > 0) {
            insertRoomLeaseState(feLeaseRecord);
            feLeaseRecord.setRoomIds(JSON.toJSONString(feLeaseRecord.getRoomIdList()));
        }
        return feLeaseRecordMapper.insertFeLeaseRecord(feLeaseRecord);
    }

    private void insertRoomLeaseState(FeLeaseRecord feLeaseRecord) {
        feLeaseRecord.getRoomVOList().forEach(roomId -> {
            BuiRoom buiRoom = roomManager.selectBuiRoomById(roomId.getId());
            buiRoom.setLeaseState(LeaseStateEnum.已租.getCode());
            buiRoom.setContractArea(roomId.getContractArea());
            buiRoom.setRecordId(feLeaseRecord.getId());
            roomManager.updateRoom(buiRoom);
            /*R<BuiRoom> r = roomService.getBuiRoom(roomId.getId());
            if (r.getCode() == HttpStatus.SUCCESS) {
                BuiRoom buiRoom = r.getData();
                buiRoom.setLeaseState(LeaseStateEnum.已租.getCode());
                buiRoom.setContractArea(roomId.getContractArea());
                buiRoom.setRecordId(feLeaseRecord.getId());
                roomService.updateRoom(buiRoom);
            }*/
        });
    }

    /**
     * 修改租赁记录
     *
     * @param feLeaseRecord 租赁记录
     * @return 结果
     */
    @Override
    public int updateFeLeaseRecord(FeLeaseRecord feLeaseRecord) {
        feLeaseRecord.setUpdateTime(DateUtils.getNowDate());
        feLeaseRecord.setUpdateBy(SecurityUtils.getUsername());

        linkFile(feLeaseRecord.getFileIdList(), feLeaseRecord.getId());

        if (CollectionUtil.isNotEmpty(feLeaseRecord.getRoomVOList())) {
            clearRoomLeaseState(feLeaseRecord.getId());
            insertRoomLeaseState(feLeaseRecord);
            feLeaseRecord.setRoomIds(JSON.toJSONString(feLeaseRecord.getRoomVOList().stream().map(RoomVO::getId).collect(Collectors.toList())));
        }

//        if (feLeaseRecord.getRoomIdList() != null && feLeaseRecord.getRoomIdList().size() > 0) {
//            clearRoomLeaseState(feLeaseRecord.getId());
//            feLeaseRecord.setRoomIds(JSON.toJSONString(feLeaseRecord.getRoomIdList()));
//        }

        String feeId = IdUtil.getSnowflake(0, 0).nextIdStr();
        // 插入或者更新租金
        FeOffice office = feLeaseRecord.getFeOffice();
        if (office != null) {
            if (StringUtils.isBlank(office.getId())) {
                office.setId(feeId);
                feLeaseRecord.setOfficeFeeId(feeId);
                feOfficeMapper.insertFeOffice(office);
            } else {
                feOfficeMapper.updateFeOffice(office);
            }
        }

        // 插入或者更新物业收费
        FeProperty property = feLeaseRecord.getFeProperty();
        if (property != null) {
            if (StringUtils.isBlank(property.getId())) {
                property.setId(feeId);
                property.setEnterpriseId(feLeaseRecord.getEnterpriseId());
                property.setLeaseRecordId(feLeaseRecord.getId());
                feLeaseRecord.setPropertyFeeId(feeId);
                fePropertyMapper.insertFeProperty(property);
            } else {
                fePropertyMapper.updateFeProperty(property);
            }
        }

        //插入或者更新设施使用费
        if (feLeaseRecord.getFeFacility() != null) {
            FeFacility facility = initFacilityFe(feLeaseRecord.getFeFacility());
            if (StringUtils.isBlank(facility.getId())) {
                facility.setId(feeId);
                feLeaseRecord.setFacilityFeeId(feeId);
                feFacilityMapper.insertFeFacility(facility);
            } else {
                feFacilityMapper.updateFeFacility(facility);
            }
        }
        if (feLeaseRecord.getFeSurety() != null) {
            FeSurety surety = feLeaseRecord.getFeSurety();
            if (StringUtils.isBlank(surety.getId())) {
                surety.setId(feeId);
                surety.setLeaseId(feLeaseRecord.getId());
                surety.setEnterpriseId(feLeaseRecord.getEnterpriseId());
                suretyMapper.insertFeSurety(surety);
            } else {
                suretyMapper.updateFeSurety(surety);
            }
        }


        return feLeaseRecordMapper.updateFeLeaseRecord(feLeaseRecord);
    }


    private FeFacility initFacilityFe(FeFacility feFacility) {
        String[] first = feFacility.getFirstFacilityFee().split("/");
        String[] second = feFacility.getSecondFacilityFee().split("/");
        String[] third = feFacility.getThirdFacilityFee().split("/");
        String[] fourth = feFacility.getFourthFacilityFee().split("/");
        String[] fifth = feFacility.getFifthFacilityFee().split("/");
        feFacility.setFirstYearFacilityFee(BigDecimal.valueOf(Double.parseDouble(first[0])));
        feFacility.setSecondYearFacilityFee(BigDecimal.valueOf(Double.parseDouble(second[0])));
        feFacility.setThirdYearFacilityFee(BigDecimal.valueOf(Double.parseDouble(third[0])));
        feFacility.setFourthYearFacilityFee(BigDecimal.valueOf(Double.parseDouble(fourth[0])));
        feFacility.setFifthYearFacilityFee(BigDecimal.valueOf(Double.parseDouble(fifth[0])));
        if (first.length > 1) {
            feFacility.setFirstYearTotal(BigDecimal.valueOf(Double.parseDouble(first[1])));
        } else {
            feFacility.setFirstYearTotal(BigDecimal.valueOf(Double.parseDouble(first[0])));
        }
        if (second.length > 1) {
            feFacility.setSecondYearTotal(BigDecimal.valueOf(Double.parseDouble(second[1])));
        } else {
            feFacility.setSecondYearTotal(BigDecimal.valueOf(Double.parseDouble(second[0])));
        }
        if (third.length > 1) {
            feFacility.setThirdYearTotal(BigDecimal.valueOf(Double.parseDouble(third[1])));
        } else {
            feFacility.setThirdYearTotal(BigDecimal.valueOf(Double.parseDouble(third[0])));
        }
        if (fourth.length > 1) {
            feFacility.setFourthYearTotal(BigDecimal.valueOf(Double.parseDouble(fourth[1])));
        } else {
            feFacility.setFourthYearTotal(BigDecimal.valueOf(Double.parseDouble(fourth[0])));
        }
        if (fifth.length > 1) {
            feFacility.setFifthYearTotal(BigDecimal.valueOf(Double.parseDouble(fifth[1])));
        } else {
            feFacility.setFifthYearTotal(BigDecimal.valueOf(Double.parseDouble(fifth[0])));
        }
        return feFacility;

    }


    /**
     * 批量删除租赁记录
     *
     * @param ids 需要删除的租赁记录ID
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteFeLeaseRecordByIds(String[] ids) {
        deleteLinkFile(ids);
        Arrays.stream(ids).forEach(id -> {
                    FeLeaseRecord o = selectFeLeaseRecordById(id);
                    feOfficeMapper.deleteFeOfficeById(o.getOfficeFeeId());
                    feFacilityMapper.deleteFeFacilityById(o.getFacilityFeeId());
                    fePropertyMapper.deleteFePropertyById(o.getPropertyFeeId());
                    suretyMapper.deleteFeSuretyByLeaseId(o.getId());
                    clearRoomLeaseState(o.getId());
                }
        );
        return feLeaseRecordMapper.deleteFeLeaseRecordByIds(ids);
    }

    /**
     * 清除设备的租赁状态
     *
     * @param recordId 租赁记录id
     */
    private void clearRoomLeaseState(String recordId) {
        BuiRoom buiRoom = new BuiRoom();
        buiRoom.setRecordId(recordId);
        List<BuiRoom> buiRoomList = roomManager.selectBuiRoomList(buiRoom);
        buiRoomList.forEach(room->{
            room.setRecordId("");
            room.setLeaseState(LeaseStateEnum.待租.getCode());
            room.setContractArea(new BigDecimal(0));
            roomManager.updateRoom(room);
        });
/*        R<List<BuiRoom>> r = roomService.listRoom(buiRoom);
        if (r.getCode() == HttpStatus.SUCCESS) {
            r.getData().forEach(room -> {
                room.setRecordId("");
                room.setLeaseState(LeaseStateEnum.待租.getCode());
                room.setContractArea(new BigDecimal(0));
                roomService.updateRoom(room);
            });
        }*/
    }

    /**
     * 删除租赁记录信息
     *
     * @param id 租赁记录ID
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteFeLeaseRecordById(String id) {
        FeLeaseRecord o = selectFeLeaseRecordById(id);
        feOfficeMapper.deleteFeOfficeById(o.getOfficeFeeId());
        feFacilityMapper.deleteFeFacilityById(o.getFacilityFeeId());
        fePropertyMapper.deleteFePropertyById(o.getPropertyFeeId());
        suretyMapper.deleteFeSuretyByLeaseId(o.getId());
        clearRoomLeaseState(o.getId());
        return feLeaseRecordMapper.deleteFeLeaseRecordById(id);
    }

    /**
     * 通过租赁记录id 查询房屋信息
     *
     * @param recordId 租赁记录ID
     * @return
     */
    @Override
    public List<RoomVO> selectRoomByRecordId(String recordId) {
        return feLeaseRecordMapper.selectRoomByRecordId(recordId);
    }

    @Override
    public int delByFeLeaseRecordByEnterpriseId(String enterpriseId) {
        FeLeaseRecord queryRecord = new FeLeaseRecord();
        queryRecord.setEnterpriseId(enterpriseId);
        List<FeLeaseRecord> list = feLeaseRecordMapper.selectFeLeaseRecordList(queryRecord);
        if (CollectionUtil.isEmpty(list)) {
            return 0;
        }
        list.stream().forEach(o -> {
            feOfficeMapper.deleteFeOfficeById(o.getOfficeFeeId());
            feFacilityMapper.deleteFeFacilityById(o.getFacilityFeeId());
            fePropertyMapper.deleteFePropertyById(o.getPropertyFeeId());
            suretyMapper.deleteFeSuretyByLeaseId(o.getId());
            clearRoomLeaseState(o.getId());
            feLeaseRecordMapper.deleteFeLeaseRecordById(o.getId());
        });
        return 1;
    }

    @Override
    public int createBill(CreateBillVo createBillVo) {
        FeBill feBill = new FeBill();

        FeLeaseRecord record = selectFeLeaseRecordById(createBillVo.getId());

        feBill.setBeginDate(createBillVo.getBillBeginDate());
        feBill.setEndDate(createBillVo.getBillEndDate());
        feBill.setDeadline(createBillVo.getBillDeadline());

        if (createBillVo.getBillType().equals("办公费用")) {
            feBill.setFeeType(FeeTypeEnum.OFFICE.getCode());
            feBill.setFeeTypeName(FeeTypeEnum.OFFICE.getType());
            //
            FeOffice office = new FeOffice();
            office.setNextRentDate(createBillVo.getBillNextDay());
            office.setId(record.getOfficeFeeId());
            feOfficeMapper.updateFeOffice(office);


        } else if (createBillVo.getBillType().equals("设施费用")) {
            feBill.setFeeType(FeeTypeEnum.FACILITY.getCode());
            feBill.setFeeTypeName(FeeTypeEnum.FACILITY.getType());

            FeFacility facility = new FeFacility();
            facility.setNextRentDate(createBillVo.getBillNextDay());
            facility.setId(record.getFacilityFeeId());
            feFacilityMapper.updateFeFacility(facility);
        } else if (createBillVo.getBillType().equals("物业费用")) {
            feBill.setFeeType(FeeTypeEnum.PROPERTY.getCode());
            feBill.setFeeTypeName(FeeTypeEnum.PROPERTY.getType());
            FeProperty property = new FeProperty();
            property.setNextPropertyDate(createBillVo.getBillNextDay());
            property.setId(record.getPropertyFeeId());
            fePropertyMapper.updateFeProperty(property);
        }
        feBill.setReceivableAmount(createBillVo.getBillMoney());
        feBill.setPayState("0");
        feBill.setRecordId(record.getId());
        feBill.setTotalArea(record.getContractArea());
        feBill.setEnterpriseName(record.getEnterpriseName());
        feBill.setEnterpriseId(record.getEnterpriseId());
        feBill.setBillNum(genBillCode());

        return billService.insertFeBill(feBill);
    }

    @Override
    public List<QyEnterpriseOtherFeeVO> selectOtherFeeList(FeLeaseRecord feLeaseRecord) {
        return feLeaseRecordMapper.selectOtherFeeList(feLeaseRecord);
    }

    @Override
    public QyEnterpriseOtherFeeVO selectOtherFeeById(String id) {
        return feLeaseRecordMapper.selectOtherFeeById(id);
    }

    @Override
    public int updateOtherFee(QyEnterpriseOtherFeeVO vo) {
        return feLeaseRecordMapper.updateOtherFee(vo);
    }

    @Autowired
    private RedisService redisService;

    private String genBillCode() {
        String date = DateUtil.format(DateUtil.date(), "yyyyMMdd");
        Integer v = redisService.getCacheObject(date);

        String result = "";
        if (v == null) {
            v = 0;
            redisService.setCacheObject(date, v,24L, TimeUnit.HOURS);
        } else {
            v = v + 1;
            redisService.setCacheObject(date, v);
        }
        String fs = String.format("%03d", v);
        result = "B" + date + fs;
        return result;
    }
}
